﻿using System;
using System.Text;
using System.Windows.Forms;
using WindowsFormsAero;

namespace BGShell.Forms
{
    internal sealed partial class HelpForm : AeroForm, IBGShellHelpContext
    {
        private BGShellHelpTopic _currentTopic;
        private String _stylesheet;

        private Boolean _isLoading;

        public HelpForm()
        {
            InitializeComponent();

            Icon = Resources.HelpIcon;

#if DEBUG
            browser.ScriptErrorsSuppressed = false;
#endif
        }

        public void Navigate(BGShellHelpTopic topic)
        {
            if (topic != null)
            {
                try
                {
                    _currentTopic = topic;
                    browser.Navigate("about:blank");
                }
                catch
                {
                    _currentTopic = null;
                    throw;
                }
            }
        }

        private void OnDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            if (_currentTopic != null)
            {
                _isLoading = true;

                var result = new StringBuilder();

                result.Append("<html><head><style>");
                result.Append(Stylesheet);
                result.Append("</style><title>");
                result.Append(_currentTopic.Title);
                result.Append("</title></head><body>");

                browser.Document.Write(result.ToString());

                _currentTopic.BeginWriteHtml(this);
            }
        }

        private string Stylesheet
        {
            get
            {
                if (_stylesheet == null)
                {
                    _stylesheet = Resources.HelpStylesheet;
                }

                return _stylesheet;
            }
        }

        private void WriteHtml(string html)
        {
            if (_isLoading)
            {
                browser.Document.Write(html);
            }
        }

        private void Done()
        {
            if (_isLoading)
            {
                _isLoading = false;
                browser.Document.Write("</body></html>");

                var anchors = browser.Document.GetElementsByTagName("a");

                foreach (HtmlElement a in anchors)
                {
                    a.Click += new HtmlElementEventHandler(OnAnchorClick);
                }
            }
        }

        void OnAnchorClick(object sender, HtmlElementEventArgs e)
        {
            if (_currentTopic != null)
            {
                var anchor = (sender as HtmlElement);

                if (anchor != null)
                {
                    var url = anchor.GetAttribute("href");

                    if (!string.IsNullOrEmpty(url) && url.StartsWith("about:", StringComparison.OrdinalIgnoreCase))
                    {
                        url = url.Substring("about:".Length);
                    }

                    if (!string.IsNullOrEmpty(url))
                    {
                        Navigate(_currentTopic.Navigate(url));
                    }
                }
            }

            e.ReturnValue = false;
        }

        void IBGShellHelpContext.WriteHtml(string html)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new Action<String>(WriteHtml), html);
            }
            else
            {
                WriteHtml(html);
            }
        }

        void IBGShellHelpContext.Done()
        {
            if (InvokeRequired)
            {
                BeginInvoke(new CrossAppDomainDelegate(Done));
            }
            else
            {
                Done();
            }
        }
    }
}
